#include "stm32f10x.h"
#include "UART.h"
#include "GPRS.h"
#include "GPS.h"
#include "stm32f10x_iwdg.h"
#include "flash.h"
#include "SD.h"
#include "stdio.h"

/*******************一下是uCOS-II需要调用的库函数******************/
#include "uCOS_Include.h"
#include "App.h"

int16_t Speed_Compare;
int16_t Speed_Compare1;
int16_t Speed_Compare2;
u8 		Compare_Fail=0;

extern OS_EVENT *Sem;
extern OS_FLAG_GRP *Flag_Grp;

INT8U  Rev_Buf;
u8  Respond_Time=0;
u8  Speed_Detection_Count=0;
u8  Speed_Detection=0;

extern u8 Stop_Time_Over;
extern u8 Buf_flag;
extern u8 GPRS_Send_flag;
extern u16 point;		 	//表示第几个弯道
extern uint16_t Straight_Speeding_Value;
extern uint16_t Corner_Speeding_Value;
extern uint16_t Other_Speeding_Value;
extern int32_t Weidu,Jingdu;  
extern u8 Statue;		 	//定位状态
extern u8 Buf_Send_flag;
extern u8 Buf_Start;
extern u8 Rev_Data[120];
extern u8 Rev_Data_Buff[120];

extern u8 Function_Word[3];

extern u8 Alarm_Location_W;	//报警区域位置显示
extern u8 Alarm_Location_Z;	//报警区域位置显示

u8 PC_Command=0;
uint16_t Update_Rate=20; //12-3s上传一次数据
u8 GPRS_REV_OK=0;

extern u8 sent_CMD;

extern u32 SendDataNumber;

Function_cb g_send_cb = NULL;
Function_cb g_old_send_cb = NULL;
u8 send_time = 0;		// 发送超时次数
u8 heart_rate_respose = 0;

u8 Modify_Compelet_Flag=0;

void Recev_Date_Proc(u8 Rec_Dat[]);
/***************************************************************/
/******************以下为uCOS_II相关程序**********************/
/***************************************************************/




 /******************************************************
函数功能：SYSTICK 配置，产生UCOS时钟节拍
           1ms一次systick中断，产生ucos 调度节拍， 1KHz
		   OS_TICKS_PER_SEC	宏定义  
		   1000表示 1/1000s 即1ms
		   100 表示 1/100s	 即10ms

函数入口：无
函数出口：无
编写时间：2012年1月11日14:56:36
编写作者：刘文翔
*************************************************/

void  OS_CPU_SysTickInit(void)
{
   
    RCC_ClocksTypeDef  rcc_clocks;		 //定义一个时钟频率结构体
    INT32U         cnts;				 //写入Systick重载寄存器的计数初值


    RCC_GetClocksFreq(&rcc_clocks);	   //读取AHB总线频率

    cnts = (INT32U)rcc_clocks.HCLK_Frequency/OS_TICKS_PER_SEC;	//计算计数初值

	SysTick_Config(cnts);	//写入计数初值
 
}


 /******************************************************
函数功能：读取CPU分频
函数入口：无
函数出口：CPU分频
*************************************************/
INT32U  BSP_CPU_ClkFreq (void)
{
    RCC_ClocksTypeDef  rcc_clocks;


    RCC_GetClocksFreq(&rcc_clocks);

    return ((INT32U)rcc_clocks.HCLK_Frequency);
}

//0x2c,GPS数据无效时整段程序执行时间大约44ms
static void APP_Task_GPS(void)
{
	INT8U err;

	while(1)
	{							 
		OSFlagPend(Flag_Grp,0x01,OS_FLAG_WAIT_SET_ALL+OS_FLAG_CONSUME,0,&err);		
//		 IWDG_ReloadCounter();
		//if((Heart_Flag++)>40 && sent_CMD)
		if((Heart_Flag++)>40)	// 10s 无响应则重新创建链路
        {
			LOG("Time out");
            Heart_Flag = 0;
			if(g_send_cb != NULL)
			{
				LOG("Resend:%X,Times:%d, %08X", g_send_cb, send_time,SendDataNumber);
				g_send_cb();		// 重新发送指令

				if(g_old_send_cb != g_send_cb)
				{
					send_time = 0;		// 与上次不是同个调用则清除发送超时累计次数
					g_old_send_cb = g_send_cb;
				}
				
				if( ++send_time > 2)
				{
					send_time = 0;
					AT_Command(0x10);
				}
			}
			else
			{
				AT_Command(0x10);		  //创建透传链路
			}
			
        }

		if(Respond_Time>13)
		{
		   Respond_Time=0;
		}	
		else
		{
			Respond_Time++;
		}
		
		if(Stop_Time_Over>13)
		{
		   Stop_Time_Over=0;
		}
		else
		{
		  Stop_Time_Over++;
		}
								 		 
		if(Statue=='A')
        //if(1)            
		{
			
			Statu_Flag=1;         						//数据有效，则置1
			//GPIO_ResetBits(GPIOA,GPIO_Pin_1);			//GPS数据有效，则GPS信号灯亮
			GPIO_ResetBits(GPIOA,GPIO_Pin_11);			//GPS数据有效，则GPS信号灯亮

			if(Other_Speeding_Value==0)
			{
				GPIO_ResetBits(GPIOA,GPIO_Pin_5);
				GPIO_ResetBits(GPIOA,GPIO_Pin_6);
			}
			else
			{
				if((Alarm_Location_Z!=0)||(Alarm_Location_W!=0))   //景区内
				{
					Speed_Detection_Z();    //直道超速检测
					Corner_Detection();		//进弯检测，弯道超速检测，进弯语音提示				
					Speed_Detection_W(); 	//弯道超速检测
					GPIO_SetBits(GPIOA,GPIO_Pin_5);
				}
				else
				{											 //景区外
					GPIO_ResetBits(GPIOA,GPIO_Pin_5);					
					Speed_Detection_Z(); 					
				    Corner_Detection();		//进弯检测，弯道超速检测，进弯语音提示						
				}
			}

			GPS_Number++;
			if(!Speed_Detection)	   //第一次系统启动时，进行计数
			{
			   Speed_Detection_Count++;
			   if(Speed_Detection_Count>160)  //40s内不进行超速检测
			   {
				   Speed_Detection_Count=0;
				   Speed_Detection=1;
			   }
			}

			Get_Speed_Value();
			//LOG("speed:%d\n",Speed_Compare);
			if(!Compare_Fail)						//系统第一次执行，获取速度值
			{	
		    	Compare_Fail=1;
//				UART2_SendString("Compare_Fail=0\n");
				Speed_Compare1=Speed_Compare;
			}
				
			if(GPS_Number>=Update_Rate)						   //GPRS每5s发一次数据
			{
//				LOG("Update_Rate\n");
				GPS_Number=0;
//				GPS_Parse();
								
				Speed_Compare2=Speed_Compare;
				if((Speed_Compare1-Speed_Compare2<30)&&(Speed_Compare1-Speed_Compare2>-30))
				 {					  
					  Speed_Compare1=Speed_Compare2;
					  Compare_Fail=1;					  					  
					  GPS_Data_Buffer_Send();
				//	  UART2_SendString("GPS_Data_Buffer_Send\n");								  
				 }
				 else
				 {
					Compare_Fail++;
					if(Compare_Fail>4)
					{
						Compare_Fail=0;	
//						UART2_SendString("Compare_Fail++\n");					
					}
					else
					{									  
						GPS_Number=Update_Rate;
//						UART2_SendString("Continue\n");
					}
				 }												
				Respond_Time=0;		  //延时确保数据回复成功
			//	OSFlagPost(Flag_Grp,0x02,OS_FLAG_SET,&err);
			}
			if(GPS_Number==(Update_Rate/2)&&Buf_Start==1)						   //GPRS每1.25s发一次数据
			{				
//				GPS_Parse();
				Buf_Send_flag=1;
			//	GPRS_Send_flag=1;
			//	OSFlagPost(Flag_Grp,0x02,OS_FLAG_SET,&err);
			}			
		}
		else
		{			
		    GPS_Number++;
			//GPIO_SetBits(GPIOA,GPIO_Pin_1);		   //GPS数据无效，则GPS信号灯灭
			
			GPIO_SetBits(GPIOA,GPIO_Pin_11);//GPS数据无效，则GPS信号灯灭
			
			Statu_Flag=0;			
			
			if(GPS_Number>=Update_Rate)
			{	
				GPS_Number=0;	
				Respond_Time=0;		//延时确保数据回复成功	
					
			//	GPS_TO_GPRS_Data();				
			//	Buf_flag=1;
			//	GPRS_Send_flag=1;
							
			}
			if(GPS_Number==(Update_Rate/2)&&Buf_Start==1)						   //GPRS每2.5s发一次数据
			{				
				Buf_Send_flag=1;
			//	GPRS_Send_flag=1;
			}
		}																  
	}
}



u8 Id_Read(void)
{
	 u8 i=0,j=0,k=0;

	 if(id[0]==0xff||id[0]==0x30||id[0]==0x00)
	 {		 
		AT_Command(0x08);
		while(!GPRS_REV_OK);
		GPRS_REV_OK=0;
		OSTimeDlyHMSM(0,0,6,0);
		for(i=0;i<3;i++)
		{
			UART1Write("AT+CPBR=1\r");
			while(!GPRS_REV_OK);		
		    GPRS_REV_OK=0;	
		    if(Rec_GPRS[0]=='+')
		    {	 
				k=8;
			   while(Rec_GPRS[k++]!=0x22)
			   {
			   	 if(k>0x30)
				 {
				    return 0;
				 }
			   }
			   for(j=0;j<4;j++)
			   {
				  id[j]=Rec_GPRS[k++];
			   }
			   Other_Modify();
			   PC_Command=0;
			   return 1;
		    }
			OSTimeDlyHMSM(0,0,6,0);
		}
		return 0;			
	}
	return 0;
	 
}

static void APP_Task_GPRS(void)	  
{
	
	
//	 Id_Read();	
//	 UART1Write("AT+CSQ\r");
	 GPRS_REV_OK=0;

	 AT_Command(0x10);				//发送创建透传链路
//	 UART1Write("AT+CPIN?\r");
	 while(1)
	 {	 	 
	    if(GPRS_REV_OK)
		{
			GPRS_REV_OK=0;
			ReturnMessage_Deal();  //处理接收的回复信息
		}				
		if(GPRS_Init_OK)
		{				   			
			//LOG("PC_Command:%d",PC_Command);
			if(!PC_Command)
			{
			  GPRS_Send_Data(); //有报警信息则启动发送数据，没有报警信息则2.5秒钟发送一次,
							 //如果CPU空闲，而缓存数组中还要没有上传成功的报警信息，则上传报警信息			 
			}
			else
			{			    
				if(Respond_Time>8)
				{
					PC_Command=0;						
					GPS_Number=0;	//下次发送数据时需间隔一次，延时确保数据回复成功		
					GPRS_Send_flag=0;		
					Modify_Response(Function_Word);
				}
			}
						
		}	
		else
		{
			if(Buf_flag==1&&GPRS_Send_flag==1)	  //如果报警信息没发生成功，则先缓存在报警数组Alarm_Information	中
			{
				GPRS_Send_flag=0;
				Buf_flag=0;	
				Buf_Send_flag=0;										
				GPRS_Buf();
				
			}
		}		
	}		  
}
 /******************************************************
函数功能：其他任务的建立
函数入口：无
函数出口：无
*************************************************/
void  

App_TaskCreate (void)
{
// 	INT8U  os_err;			//无符号八位变量，用来存储任务建立的返回值

//	IWDG_int();

	OSTaskCreateExt((void (*)(void *)) APP_Task_LED,
                (void          * ) 0,
                (OS_STK        * )&App_Task_LED_Stk[APP_TASK_LED_STK_SIZE - 1],
                (INT8U           ) APP_TASK_LED_PRIO,	 //设置起始任务的优先级
				 APP_TASK_LED_PRIO,
				 (OS_STK        * )&App_Task_LED_Stk[0],
				 APP_TASK_LED_STK_SIZE,
				 (void			*)0,
				 OS_TASK_OPT_STK_CLR
				);
						   	
	OSTaskCreateExt((void (*)(void *)) APP_Task_GPS,
                    (void          * ) 0,
                    (OS_STK        * )&App_Task_GPS_Stk[APP_TASK_GPS_STK_SIZE - 1],
                    (INT8U           ) APP_TASK_GPS_PRIO,	 //设置起始任务的优先级
					 APP_TASK_GPS_PRIO,
					 (OS_STK        * )&App_Task_GPS_Stk[0],
					 APP_TASK_GPS_STK_SIZE,
					 (void			*)0,
					 OS_TASK_OPT_STK_CLR
					);
	OSTaskCreateExt((void (*)(void *)) APP_Task_GPRS,
                    (void          * ) 0,
                    (OS_STK        * )&App_Task_GPRS_Stk[APP_TASK_GPRS_STK_SIZE - 1],
                    (INT8U           ) APP_TASK_GPRS_PRIO,	 
					 APP_TASK_GPRS_PRIO,
					 (OS_STK        * )&App_Task_GPRS_Stk[0],
					 APP_TASK_GPRS_STK_SIZE,
					 (void			*)0,
					 OS_TASK_OPT_STK_CLR
					);	
	OSTaskCreateExt((void (*)(void *)) APP_Task_Modify,
                    (void          * ) 0,
                    (OS_STK        * )&App_Task_Modify_Stk[APP_TASK_Modify_STK_SIZE - 1],
                    (INT8U           ) APP_TASK_Modify_PRIO,	 
					 APP_TASK_Modify_PRIO,
					 (OS_STK        * )&App_Task_Modify_Stk[0],
					 APP_TASK_Modify_STK_SIZE,
					 (void			*)0,
					 OS_TASK_OPT_STK_CLR
					);									   
}

static void APP_Task_Modify(void *p_arg)
{
    u8 Temp;
	INT8U err;
	(void)p_arg;
	while(1)
	{
		OSFlagPend(Flag_Grp,0x04,OS_FLAG_WAIT_SET_ALL+OS_FLAG_CONSUME,0,&err);
		Recev_Date_Proc(Rev_Data_Buff);
		if(Rev_Data[0]==0x2a)
		{
			Function_Word[0]=Rev_Data[7];
			Function_Word[1]=Rev_Data[8];
	
			Temp=Rev_Data[7];
			switch(Temp)
			  {
			   
			   case 'X':{
			   			   switch(Rev_Data[8])
						   {
						   		case 'A':Corner_Modify(Rev_Data);break;
								case 'B':Corner_Modify(Rev_Data);break;
								case 'C':Stand_Modify(Rev_Data);break;
								case 'D':Stand_Modify(Rev_Data);break;
								case 'E':Modify_Speed(Rev_Data);break;
								default : break;
						   }
						   break;
						}
			   case 'A':Modify_Id(Rev_Data);break;
			   case 'B':Modify_Update_Rate(Rev_Data);break;
			   case 'D':Modify_IP(Rev_Data);break;
			   case 'Y':{	//语音检测
			   				Send_Command(0x00);
							GPIO_ResetBits(GPIOB,GPIO_Pin_9);
						    Delay_1ms(500);	 	  
						    GPIO_SetBits(GPIOB,GPIO_Pin_9);
							break;	
						}
			   case 'P':{	//GPS检测
							if(Statue=='A')		   //GPS数据 正常
							{
							   UART3_SendString("*A#");
							}
							else
							{
							   UART3_SendString("*V#");
							}
			   				break;
						}
			   case 'S':{	//GSM检测							
							if(GPRS_Init_OK)		   //GSM数据 正常
							{
							   UART3_SendString("*O#");
							}
							else
							{
							   UART3_SendString("*L#");
							}
			   				break;
						}
			   default:break;
			}
		}
		else
		{
			AT_Command(0x04);
		}
		Modify_Compelet_Flag=0;
	}
}
void Recev_Date_Proc(u8 Rec_Dat[])
{
	  u8 i=0;
	  while(Rec_Dat[2*i]!=0x00)
	  {
	    if(Rec_Dat[2*i]>0x40)
		{
		   		   
		   Rec_Dat[2*i]=Rec_Dat[2*i]-0x07;
		   
		}		
		if(Rec_Dat[2*i+1]>0x40)
		{
		   Rec_Dat[2*i+1]=Rec_Dat[2*i+1]-0x07;		   
		}		
		Rev_Data[i]=(Rec_Dat[2*i]-0x30)*16+Rec_Dat[2*i+1]-0x30;		
		i++	 ;
	  }
}
static void APP_Task_LED(void *p_arg)
{
	  INT8U err;
	  (void)p_arg;
	  while(1)
	  {	  	   	  
		  IWDG_ReloadCounter();
	  	  
		  OSFlagAccept(Flag_Grp,0x02,OS_FLAG_WAIT_SET_ALL,&err);
		  if(err==OS_ERR_NONE)
		  {
			 GPIO_ResetBits(GPIOB,GPIO_Pin_9);//蜂鸣器
			 OSTimeDlyHMSM(0,0,0,500);  
			 GPIO_SetBits(GPIOB,GPIO_Pin_9);
			 OSTimeDlyHMSM(0,0,0,500); 
		  }
		  else
		  {
			  // Modified by yc 20160703
			 //GPIO_ResetBits(GPIOA,GPIO_Pin_11);
			 GPIO_ResetBits(GPIOA,GPIO_Pin_5);				  
			 OSTimeDlyHMSM(0,0,1,0);	
			 //GPIO_SetBits(GPIOA,GPIO_Pin_11);	
			  GPIO_SetBits(GPIOA,GPIO_Pin_5);	
			 OSTimeDlyHMSM(0,0,1,0); 
		  }
		  
		  // 接收到心跳包的返回数据，给发送方通知
		  if(heart_rate_respose == 1)
		  {
			  heart_rate_respose = 0;
				OSFlagPost(Flag_Grp, 0x08, OS_FLAG_SET, &err);
		  }
	  }
}

 /******************************************************
函数功能：最初任务的调用
函数入口：void *p_arg（无意义）
函数出口：无

*************************************************/
void App_TaskStart (void *p_arg)
{
	(void)p_arg;	//传递变量为空，防止编译错误
		
	App_TaskCreate( );	//开始创建多任务 
	 while(1)
	 OSTaskSuspend(OS_PRIO_SELF);  //最高优先任务挂起
}






